package main

import (
	"bytes"
	"fmt"
	"io"

	"github.com/syndtr/goleveldb/leveldb"
)

type (
	fullNode struct {
		Children [17]node // Actual trie node data to encode/decode (needs custom encoder)
		flags    nodeFlag
	}
	shortNode struct {
		Key   []byte
		Val   node
		flags nodeFlag
	}
	hashNode  []byte
	valueNode []byte
)

func dump(db *leveldb.DB, n node, depth int, s []byte) {
	switch fn := n.(type) {
	case *fullNode:
		for i, h := range fn.Children {
			if h != nil {
				fmt.Println(ws(depth)+"child ", toString(s))
				dump(db, h, depth+1, append(s, byte(i)))
			}
		}
	case *shortNode:
		fmt.Println(ws(depth)+"ShortNode", fn.String())
		k := hexToKeybytes(append(s, fn.Key...))
		fmt.Println(ws(depth)+"ShortNode Key", fmt.Sprintf("%x ", k))
		dump(db, fn.Val, depth+1, s)
	case hashNode:
		fmt.Println(ws(depth)+toString(s)+":hash Node", fn.String())
		dumpKey(db, fn, depth+1, s)
	case valueNode:
		fmt.Println(ws(depth)+toString(s)+":value Node", fn.String())
		buf := bytes.NewBuffer(fn)
		s := rlp.NewStream(buf, 0)
		for {
			if err := rlpdump(db, s, 0); err != nil {
				if err != io.EOF {
				}
				break
			}
			fmt.Println()
		}
	}
}
